<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><link rel="stylesheet" type="text/css" href="style.css" /><script type="text/javascript" src="highlight.js"></script></head><body><pre><span class="hs-pragma">{-# LANGUAGE Trustworthy #-}</span><span>
</span><span id="line-2"></span><span class="hs-pragma">{-# LANGUAGE StandaloneDeriving #-}</span><span>
</span><span id="line-3"></span><span class="hs-pragma">{-# LANGUAGE MagicHash #-}</span><span>
</span><span id="line-4"></span><span class="hs-pragma">{-# LANGUAGE UnboxedTuples #-}</span><span>
</span><span id="line-5"></span><span>
</span><span id="line-6"></span><span class="hs-comment">-----------------------------------------------------------------------------</span><span>
</span><span id="line-7"></span><span class="hs-comment">-- |</span><span>
</span><span id="line-8"></span><span class="hs-comment">-- Module      :  System.Mem.StableName</span><span>
</span><span id="line-9"></span><span class="hs-comment">-- Copyright   :  (c) The University of Glasgow 2001</span><span>
</span><span id="line-10"></span><span class="hs-comment">-- License     :  BSD-style (see the file libraries/base/LICENSE)</span><span>
</span><span id="line-11"></span><span class="hs-comment">--</span><span>
</span><span id="line-12"></span><span class="hs-comment">-- Maintainer  :  libraries@haskell.org</span><span>
</span><span id="line-13"></span><span class="hs-comment">-- Stability   :  experimental</span><span>
</span><span id="line-14"></span><span class="hs-comment">-- Portability :  non-portable</span><span>
</span><span id="line-15"></span><span class="hs-comment">--</span><span>
</span><span id="line-16"></span><span class="hs-comment">-- Stable names are a way of performing fast ( \(\mathcal{O}(1)\) ),</span><span>
</span><span id="line-17"></span><span class="hs-comment">-- not-quite-exact comparison between objects.</span><span>
</span><span id="line-18"></span><span class="hs-comment">--</span><span>
</span><span id="line-19"></span><span class="hs-comment">-- Stable names solve the following problem: suppose you want to build</span><span>
</span><span id="line-20"></span><span class="hs-comment">-- a hash table with Haskell objects as keys, but you want to use</span><span>
</span><span id="line-21"></span><span class="hs-comment">-- pointer equality for comparison; maybe because the keys are large</span><span>
</span><span id="line-22"></span><span class="hs-comment">-- and hashing would be slow, or perhaps because the keys are infinite</span><span>
</span><span id="line-23"></span><span class="hs-comment">-- in size.  We can\'t build a hash table using the address of the</span><span>
</span><span id="line-24"></span><span class="hs-comment">-- object as the key, because objects get moved around by the garbage</span><span>
</span><span id="line-25"></span><span class="hs-comment">-- collector, meaning a re-hash would be necessary after every garbage</span><span>
</span><span id="line-26"></span><span class="hs-comment">-- collection.</span><span>
</span><span id="line-27"></span><span class="hs-comment">--</span><span>
</span><span id="line-28"></span><span class="hs-comment">-------------------------------------------------------------------------------</span><span>
</span><span id="line-29"></span><span>
</span><span id="line-30"></span><span class="hs-keyword">module</span><span> </span><span class="hs-identifier">GHC.StableName</span><span> </span><span class="hs-special">(</span><span>
</span><span id="line-31"></span><span>  </span><span class="annot"><span class="hs-comment">-- * Stable Names</span></span><span>
</span><span id="line-32"></span><span>  </span><span class="annot"><a href="GHC.StableName.html#StableName"><span class="hs-identifier">StableName</span></a></span><span> </span><span class="hs-special">(</span><span class="hs-glyph">..</span><span class="hs-special">)</span><span class="hs-special">,</span><span>
</span><span id="line-33"></span><span>  </span><span class="annot"><a href="GHC.StableName.html#makeStableName"><span class="hs-identifier">makeStableName</span></a></span><span class="hs-special">,</span><span>
</span><span id="line-34"></span><span>  </span><span class="annot"><a href="GHC.StableName.html#hashStableName"><span class="hs-identifier">hashStableName</span></a></span><span class="hs-special">,</span><span>
</span><span id="line-35"></span><span>  </span><span class="annot"><a href="GHC.StableName.html#eqStableName"><span class="hs-identifier">eqStableName</span></a></span><span>
</span><span id="line-36"></span><span>  </span><span class="hs-special">)</span><span> </span><span class="hs-keyword">where</span><span>
</span><span id="line-37"></span><span>
</span><span id="line-38"></span><span class="hs-keyword">import</span><span> </span><span class="annot"><a href="GHC.IO.html"><span class="hs-identifier">GHC.IO</span></a></span><span>           </span><span class="hs-special">(</span><span> </span><span class="annot"><a href="../../ghc-prim/src/GHC.Types.html#IO"><span class="hs-identifier">IO</span></a></span><span class="hs-special">(</span><span class="hs-glyph">..</span><span class="hs-special">)</span><span> </span><span class="hs-special">)</span><span>
</span><span id="line-39"></span><span class="hs-keyword">import</span><span> </span><span class="annot"><a href="GHC.Base.html"><span class="hs-identifier">GHC.Base</span></a></span><span>         </span><span class="hs-special">(</span><span> </span><span class="annot"><a href="../../ghc-prim/src/GHC.Types.html#Int"><span class="hs-identifier">Int</span></a></span><span class="hs-special">(</span><span class="hs-glyph">..</span><span class="hs-special">)</span><span class="hs-special">,</span><span> </span><span class="annot"><a href="../../ghc-prim/src/GHC.Prim.html#StableName%23"><span class="hs-identifier">StableName#</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><a href="../../ghc-prim/src/GHC.Prim.html#makeStableName%23"><span class="hs-identifier">makeStableName#</span></a></span><span>
</span><span id="line-40"></span><span>                        </span><span class="hs-special">,</span><span> </span><span class="annot"><a href="../../ghc-prim/src/GHC.Prim.html#eqStableName%23"><span class="hs-identifier">eqStableName#</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><a href="../../ghc-prim/src/GHC.Prim.html#stableNameToInt%23"><span class="hs-identifier">stableNameToInt#</span></a></span><span> </span><span class="hs-special">)</span><span>
</span><span id="line-41"></span><span>
</span><span id="line-42"></span><span class="hs-comment">-----------------------------------------------------------------------------</span><span>
</span><span id="line-43"></span><span class="hs-comment">-- Stable Names</span><span>
</span><span id="line-44"></span><span>
</span><span id="line-45"></span><span class="hs-comment">{-|
  An abstract name for an object, that supports equality and hashing.

  Stable names have the following property:

  * If @sn1 :: StableName@ and @sn2 :: StableName@ and @sn1 == sn2@
   then @sn1@ and @sn2@ were created by calls to @makeStableName@ on
   the same object.

  The reverse is not necessarily true: if two stable names are not
  equal, then the objects they name may still be equal.  Note in particular
  that `makeStableName` may return a different `StableName` after an
  object is evaluated.

  Stable Names are similar to Stable Pointers (&quot;Foreign.StablePtr&quot;),
  but differ in the following ways:

  * There is no @freeStableName@ operation, unlike &quot;Foreign.StablePtr&quot;s.
    Stable names are reclaimed by the runtime system when they are no
    longer needed.

  * There is no @deRefStableName@ operation.  You can\'t get back from
    a stable name to the original Haskell object.  The reason for
    this is that the existence of a stable name for an object does not
    guarantee the existence of the object itself; it can still be garbage
    collected.
-}</span><span>
</span><span id="line-72"></span><span>
</span><span id="line-73"></span><span class="hs-keyword">data</span><span> </span><span id="StableName"><span class="annot"><a href="GHC.StableName.html#StableName"><span class="hs-identifier hs-var">StableName</span></a></span></span><span> </span><span id="local-6989586621679565120"><span class="annot"><a href="#local-6989586621679565120"><span class="hs-identifier hs-type">a</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span id="StableName"><span class="annot"><a href="GHC.StableName.html#StableName"><span class="hs-identifier hs-var">StableName</span></a></span></span><span> </span><span class="hs-special">(</span><span class="annot"><a href="../../ghc-prim/src/GHC.Prim.html#StableName%23"><span class="hs-identifier hs-type">StableName#</span></a></span><span> </span><span class="annot"><a href="#local-6989586621679565120"><span class="hs-identifier hs-type">a</span></a></span><span class="hs-special">)</span><span>
</span><span id="line-74"></span><span>
</span><span id="line-75"></span><span class="hs-comment">-- | Makes a 'StableName' for an arbitrary object.  The object passed as</span><span>
</span><span id="line-76"></span><span class="hs-comment">-- the first argument is not evaluated by 'makeStableName'.</span><span>
</span><span id="line-77"></span><span id="local-6989586621679565127"><span class="annot"><a href="GHC.StableName.html#makeStableName"><span class="hs-identifier hs-type">makeStableName</span></a></span><span>  </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="#local-6989586621679565127"><span class="hs-identifier hs-type">a</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="../../ghc-prim/src/GHC.Types.html#IO"><span class="hs-identifier hs-type">IO</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.StableName.html#StableName"><span class="hs-identifier hs-type">StableName</span></a></span><span> </span><span class="annot"><a href="#local-6989586621679565127"><span class="hs-identifier hs-type">a</span></a></span><span class="hs-special">)</span></span><span>
</span><span id="line-78"></span><span id="makeStableName"><span class="annot"><span class="annottext">makeStableName :: forall a. a -&gt; IO (StableName a)
</span><a href="GHC.StableName.html#makeStableName"><span class="hs-identifier hs-var hs-var">makeStableName</span></a></span></span><span> </span><span id="local-6989586621679565104"><span class="annot"><span class="annottext">a
</span><a href="#local-6989586621679565104"><span class="hs-identifier hs-var">a</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">(State# RealWorld -&gt; (# State# RealWorld, StableName a #))
-&gt; IO (StableName a)
forall a. (State# RealWorld -&gt; (# State# RealWorld, a #)) -&gt; IO a
</span><a href="../../ghc-prim/src/GHC.Types.html#IO"><span class="hs-identifier hs-var">IO</span></a></span><span> </span><span class="annot"><span class="annottext">((State# RealWorld -&gt; (# State# RealWorld, StableName a #))
 -&gt; IO (StableName a))
-&gt; (State# RealWorld -&gt; (# State# RealWorld, StableName a #))
-&gt; IO (StableName a)
forall a b. (a -&gt; b) -&gt; a -&gt; b
</span><a href="GHC.Base.html#%24"><span class="hs-operator hs-var">$</span></a></span><span> </span><span class="hs-glyph">\</span><span> </span><span id="local-6989586621679565103"><span class="annot"><span class="annottext">State# RealWorld
</span><a href="#local-6989586621679565103"><span class="hs-identifier hs-var">s</span></a></span></span><span> </span><span class="hs-glyph">-&gt;</span><span>
</span><span id="line-79"></span><span>    </span><span class="hs-keyword">case</span><span> </span><span class="annot"><span class="annottext">a -&gt; State# RealWorld -&gt; (# State# RealWorld, StableName# a #)
forall a.
a -&gt; State# RealWorld -&gt; (# State# RealWorld, StableName# a #)
</span><a href="../../ghc-prim/src/GHC.Prim.html#makeStableName%23"><span class="hs-identifier hs-var">makeStableName#</span></a></span><span> </span><span class="annot"><span class="annottext">a
</span><a href="#local-6989586621679565104"><span class="hs-identifier hs-var">a</span></a></span><span> </span><span class="annot"><span class="annottext">State# RealWorld
</span><a href="#local-6989586621679565103"><span class="hs-identifier hs-var">s</span></a></span><span> </span><span class="hs-keyword">of</span><span> </span><span class="hs-special">(#</span><span> </span><span id="local-6989586621679565102"><span class="annot"><span class="annottext">State# RealWorld
</span><a href="#local-6989586621679565102"><span class="hs-identifier hs-var">s'</span></a></span></span><span class="hs-special">,</span><span> </span><span id="local-6989586621679565101"><span class="annot"><span class="annottext">StableName# a
</span><a href="#local-6989586621679565101"><span class="hs-identifier hs-var">sn</span></a></span></span><span> </span><span class="hs-special">#)</span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="hs-special">(#</span><span> </span><span class="annot"><span class="annottext">State# RealWorld
</span><a href="#local-6989586621679565102"><span class="hs-identifier hs-var">s'</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><span class="annottext">StableName# a -&gt; StableName a
forall a. StableName# a -&gt; StableName a
</span><a href="GHC.StableName.html#StableName"><span class="hs-identifier hs-var">StableName</span></a></span><span> </span><span class="annot"><span class="annottext">StableName# a
</span><a href="#local-6989586621679565101"><span class="hs-identifier hs-var">sn</span></a></span><span> </span><span class="hs-special">#)</span><span>
</span><span id="line-80"></span><span>
</span><span id="line-81"></span><span class="hs-comment">-- | Convert a 'StableName' to an 'Int'.  The 'Int' returned is not</span><span>
</span><span id="line-82"></span><span class="hs-comment">-- necessarily unique; several 'StableName's may map to the same 'Int'</span><span>
</span><span id="line-83"></span><span class="hs-comment">-- (in practice however, the chances of this are small, so the result</span><span>
</span><span id="line-84"></span><span class="hs-comment">-- of 'hashStableName' makes a good hash key).</span><span>
</span><span id="line-85"></span><span id="local-6989586621679565119"><span class="annot"><a href="GHC.StableName.html#hashStableName"><span class="hs-identifier hs-type">hashStableName</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.StableName.html#StableName"><span class="hs-identifier hs-type">StableName</span></a></span><span> </span><span class="annot"><a href="#local-6989586621679565119"><span class="hs-identifier hs-type">a</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="../../ghc-prim/src/GHC.Types.html#Int"><span class="hs-identifier hs-type">Int</span></a></span></span><span>
</span><span id="line-86"></span><span id="hashStableName"><span class="annot"><span class="annottext">hashStableName :: forall a. StableName a -&gt; Int
</span><a href="GHC.StableName.html#hashStableName"><span class="hs-identifier hs-var hs-var">hashStableName</span></a></span></span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.StableName.html#StableName"><span class="hs-identifier hs-type">StableName</span></a></span><span> </span><span id="local-6989586621679565100"><span class="annot"><span class="annottext">StableName# a
</span><a href="#local-6989586621679565100"><span class="hs-identifier hs-var">sn</span></a></span></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">Int# -&gt; Int
</span><a href="../../ghc-prim/src/GHC.Types.html#I%23"><span class="hs-identifier hs-var">I#</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><span class="annottext">StableName# a -&gt; Int#
forall a. StableName# a -&gt; Int#
</span><a href="../../ghc-prim/src/GHC.Prim.html#stableNameToInt%23"><span class="hs-identifier hs-var">stableNameToInt#</span></a></span><span> </span><span class="annot"><span class="annottext">StableName# a
</span><a href="#local-6989586621679565100"><span class="hs-identifier hs-var">sn</span></a></span><span class="hs-special">)</span><span>
</span><span id="line-87"></span><span>
</span><span id="line-88"></span><span class="hs-comment">-- | @since 2.01</span><span>
</span><span id="line-89"></span><span id="local-6989586621679565116"><span class="hs-keyword">instance</span><span> </span><span id="local-6989586621679565097"><span class="annot"><a href="../../ghc-prim/src/GHC.Classes.html#Eq"><span class="hs-identifier hs-type">Eq</span></a></span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.StableName.html#StableName"><span class="hs-identifier hs-type">StableName</span></a></span><span> </span><span class="annot"><a href="#local-6989586621679565116"><span class="hs-identifier hs-type">a</span></a></span><span class="hs-special">)</span></span><span> </span><span class="hs-keyword">where</span><span>
</span><span id="line-90"></span><span>    </span><span class="hs-special">(</span><span class="annot"><a href="GHC.StableName.html#StableName"><span class="hs-identifier hs-type">StableName</span></a></span><span> </span><span id="local-6989586621679565095"><span class="annot"><span class="annottext">StableName# a
</span><a href="#local-6989586621679565095"><span class="hs-identifier hs-var">sn1</span></a></span></span><span class="hs-special">)</span><span> </span><span id="local-6989586621679565094"><span class="annot"><span class="annottext">== :: StableName a -&gt; StableName a -&gt; Bool
</span><a href="../../ghc-prim/src/GHC.Classes.html#%3D%3D"><span class="hs-operator hs-var hs-var hs-var hs-var">==</span></a></span></span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.StableName.html#StableName"><span class="hs-identifier hs-type">StableName</span></a></span><span> </span><span id="local-6989586621679565093"><span class="annot"><span class="annottext">StableName# a
</span><a href="#local-6989586621679565093"><span class="hs-identifier hs-var">sn2</span></a></span></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">=</span><span>
</span><span id="line-91"></span><span>       </span><span class="hs-keyword">case</span><span> </span><span class="annot"><span class="annottext">StableName# a -&gt; StableName# a -&gt; Int#
forall a b. StableName# a -&gt; StableName# b -&gt; Int#
</span><a href="../../ghc-prim/src/GHC.Prim.html#eqStableName%23"><span class="hs-identifier hs-var">eqStableName#</span></a></span><span> </span><span class="annot"><span class="annottext">StableName# a
</span><a href="#local-6989586621679565095"><span class="hs-identifier hs-var">sn1</span></a></span><span> </span><span class="annot"><span class="annottext">StableName# a
</span><a href="#local-6989586621679565093"><span class="hs-identifier hs-var">sn2</span></a></span><span> </span><span class="hs-keyword">of</span><span>
</span><span id="line-92"></span><span>         </span><span class="annot"><span class="annottext">Int#
</span><span class="hs-number">0#</span></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><span class="annottext">Bool
</span><a href="../../ghc-prim/src/GHC.Types.html#False"><span class="hs-identifier hs-var">False</span></a></span><span>
</span><span id="line-93"></span><span>         </span><span class="annot"><span class="annottext">Int#
</span><span class="hs-identifier">_</span></span><span>  </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><span class="annottext">Bool
</span><a href="../../ghc-prim/src/GHC.Types.html#True"><span class="hs-identifier hs-var">True</span></a></span></span><span>
</span><span id="line-94"></span><span>
</span><span id="line-95"></span><span class="hs-comment">-- | Equality on 'StableName' that does not require that the types of</span><span>
</span><span id="line-96"></span><span class="hs-comment">-- the arguments match.</span><span>
</span><span id="line-97"></span><span class="hs-comment">--</span><span>
</span><span id="line-98"></span><span class="hs-comment">-- @since 4.7.0.0</span><span>
</span><span id="line-99"></span><span id="local-6989586621679565113"><span id="local-6989586621679565114"><span class="annot"><a href="GHC.StableName.html#eqStableName"><span class="hs-identifier hs-type">eqStableName</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="GHC.StableName.html#StableName"><span class="hs-identifier hs-type">StableName</span></a></span><span> </span><span class="annot"><a href="#local-6989586621679565114"><span class="hs-identifier hs-type">a</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="GHC.StableName.html#StableName"><span class="hs-identifier hs-type">StableName</span></a></span><span> </span><span class="annot"><a href="#local-6989586621679565113"><span class="hs-identifier hs-type">b</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="../../ghc-prim/src/GHC.Types.html#Bool"><span class="hs-identifier hs-type">Bool</span></a></span></span></span><span>
</span><span id="line-100"></span><span id="eqStableName"><span class="annot"><span class="annottext">eqStableName :: forall a b. StableName a -&gt; StableName b -&gt; Bool
</span><a href="GHC.StableName.html#eqStableName"><span class="hs-identifier hs-var hs-var">eqStableName</span></a></span></span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.StableName.html#StableName"><span class="hs-identifier hs-type">StableName</span></a></span><span> </span><span id="local-6989586621679565092"><span class="annot"><span class="annottext">StableName# a
</span><a href="#local-6989586621679565092"><span class="hs-identifier hs-var">sn1</span></a></span></span><span class="hs-special">)</span><span> </span><span class="hs-special">(</span><span class="annot"><a href="GHC.StableName.html#StableName"><span class="hs-identifier hs-type">StableName</span></a></span><span> </span><span id="local-6989586621679565091"><span class="annot"><span class="annottext">StableName# b
</span><a href="#local-6989586621679565091"><span class="hs-identifier hs-var">sn2</span></a></span></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">=</span><span>
</span><span id="line-101"></span><span>       </span><span class="hs-keyword">case</span><span> </span><span class="annot"><span class="annottext">StableName# a -&gt; StableName# b -&gt; Int#
forall a b. StableName# a -&gt; StableName# b -&gt; Int#
</span><a href="../../ghc-prim/src/GHC.Prim.html#eqStableName%23"><span class="hs-identifier hs-var">eqStableName#</span></a></span><span> </span><span class="annot"><span class="annottext">StableName# a
</span><a href="#local-6989586621679565092"><span class="hs-identifier hs-var">sn1</span></a></span><span> </span><span class="annot"><span class="annottext">StableName# b
</span><a href="#local-6989586621679565091"><span class="hs-identifier hs-var">sn2</span></a></span><span> </span><span class="hs-keyword">of</span><span>
</span><span id="line-102"></span><span>         </span><span class="annot"><span class="annottext">Int#
</span><span class="hs-number">0#</span></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><span class="annottext">Bool
</span><a href="../../ghc-prim/src/GHC.Types.html#False"><span class="hs-identifier hs-var">False</span></a></span><span>
</span><span id="line-103"></span><span>         </span><span class="annot"><span class="annottext">Int#
</span><span class="hs-identifier">_</span></span><span>  </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><span class="annottext">Bool
</span><a href="../../ghc-prim/src/GHC.Types.html#True"><span class="hs-identifier hs-var">True</span></a></span><span>
</span><span id="line-104"></span><span>  </span><span class="hs-comment">-- Requested by Emil Axelsson on glasgow-haskell-users, who wants to</span><span>
</span><span id="line-105"></span><span>  </span><span class="hs-comment">-- use it for implementing observable sharing.</span><span>
</span><span id="line-106"></span><span>
</span><span id="line-107"></span></pre></body></html>